<template>
	
	<view class="content">
		<!-- <view class="iconfont icon-saomayanzhen" @click="scan"></view> -->
		<button @click="initBle">检查手机</button>
		<view class="list">
			<view class="item" v-for="(item,index) in bleDevs">{{item.name ? item.name : "未知设备"}}</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				bleDevs: []
			}
		},
		onLoad() {

		},
		created(){
			
		},
		methods: {
			initBle() {
				this.bleDevs = [];
				uni.openBluetoothAdapter({
					success: (res) => { //已打开
						uni.getBluetoothAdapterState({ //蓝牙的匹配状态
							success: (row) => {
								// 开始搜索蓝牙设备
								this.startBluetoothDeviceDiscovery()
							},
							fail(error) {
								uni.showToast({
									icon: 'none',
									title: '查看手机蓝牙是否打开'
								});
							}
						});

					},
					fail: err => { //未打开 
						uni.showToast({
							icon: 'none',
							title: '查看手机蓝牙是否打开'
						});
					}
				})
			},
			// 开始搜索蓝牙设备
			startBluetoothDeviceDiscovery() {
				let _this = this
				uni.startBluetoothDevicesDiscovery({
					success: (res) => {
						// _this.timer1 = setTimeout(() => { //加个延迟、目的是为了设备搜索完毕再获取列表，不然获取为空列表
						// 	// 获取设备列表
						// 	_this.onBluetoothDeviceFound()
						// }, 1000)
						uni.onBluetoothDeviceFound(res2=>{
							console.log(res2)
							var bleDevs = _this.bleDevs
							bleDevs = bleDevs.concat(res2.devices)
							_this.bleDevs = bleDevs
						})
					},
					fail: (err)=> {
						console.log(err)
					}
				})
			},
// 获取设备列表
			onBluetoothDeviceFound() {
				let that = this
				uni.getBluetoothDevices({
					success: function(res) {
						//过滤掉name为空的设备
						that.bleDevs = res.devices
						console.log(this.bleDevs)
						// var bluetoothArr = res.devices.filter(function(obj) {
						// 	return obj.name != ""
						// })
						// that.bleDevs = bluetoothArr
						// console.log(this.bleDevs)
					},
					fail: function() {
						uni.showToast({
							title: '搜索蓝牙设备失败或附件暂无开启的蓝牙设备',
							icon: 'none',
							duration: 2000
						})
					},
					complete: function() {
						//设备获取完成之后  停止搜索
						uni.stopBluetoothDevicesDiscovery({
							success(res) {
								console.log('停止搜索蓝牙', res)
							}
						})
					}
				})
			},
//选择设备连接把deviceId传进来
			createBLEConnection(deviceId) {
				let that = this
				this.deviceId = deviceId
				this.pageLoading = true
				//连接蓝牙
				uni.createBLEConnection({
					// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
					deviceId: this.deviceId,
					success(res) {
					console.log("蓝牙连接成功", res)
						that.timer2 = setTimeout(() => {
							// 设置最大传输字节  这里根据情况自己设置
							uni.setBLEMTU({
								deviceId: that.deviceId,
								mtu: 500,//传输字节数
								success() {
									// 获取已连接设备列表
									that.getConnectedBluetoothDevices()
									// 连接成功之后  把已连接的设备从设备列表中删除
									let index = ''
									that.bleDevs.forEach((i, key) => {
										if (i.deviceId == that.deviceId) {
											index = key

										}
									})
									if (index !== '') {
										that.bleDevs.splice(index, 1)
									}
									
									that.pageLoading = false
									//获取服务 
									// that.getBLEDeviceServices()
								}
							})
						}, 1000)

					},
					fail(res) {
						console.log("蓝牙连接失败", res)
						uni.showToast({
							icon: 'none',
							title: '蓝牙连接失败'
						})
					}
				})
			},
//获取蓝牙的所有服务
			getBLEDeviceServices(deviceId) {
				let that = this
				uni.getBLEDeviceServices({
					deviceId: deviceId,
					success: (res) => {
						console.log("获取服务成功",res)
						//这里会获取到好多个services  uuid  根据实际情况选择自己需要的服务
						console.log("services", res.services)
						if (res.services.length > 0) {
							let serviceId = res.services[2].uuid //根据我们的设备  使用的是第三个服务
							that.serviceId=res.services[2].uuid
							//获取服务特征
							this.getBLEDeviceCharacteristics(deviceId, serviceId)
						}

					},
					fail(res) {
						console.log("获取蓝牙失败", res)
					}
				})
			},
//获取蓝牙特征
			getBLEDeviceCharacteristics(deviceId, serviceId) {
				console.log("------------------进入特征------------------");
				let that = this
				uni.getBLEDeviceCharacteristics({
					deviceId: deviceId,
					serviceId: serviceId,
					success: (res) => {
						console.log("res.characteristics.", res.characteristics)
						that.characteristics = res.characteristics
						// 这里哪个特征支持notify或indicate  就选择哪个
						that.characteristicId = res.characteristics[0].uuid // 接收数据的特征uuid
						that.characteristicId2 = res.characteristics[1].uuid  //发送数据的特征uuid
						that.notifyBLECharacteristicValueChange(deviceId,serviceId,that.characteristicId)
					},
					fail: (res) => {
						console.log(res)
					}
				})
			},
// 启用 notify 功能
			notifyBLECharacteristicValueChange(deviceId,serviceId,characteristicId) {
				let that = this
				uni.notifyBLECharacteristicValueChange({
					state: true, // 启用 notify 功能
					deviceId: deviceId,
					serviceId: serviceId,
					characteristicId: characteristicId,
					success: (res) => {
						//监听设备发送数据
						uni.onBLECharacteristicValueChange((res) => {
							console.log("监听成功", res.value)
							// ArrayBuffer
							//res.value是ArrayBuffer类型的，转换成需要的格式，我们再进行操作
							//这是转换成ASCII码
							let str =that.ab2ascii(res.value)
							//转换后的数据
							that.data = str
						})
					},
					fail: (res) => {
						console.log('启用 notify 功能失败', res)
						uni.showToast({
							icon:'none',
							title:'设备暂不支持接收数据',
							duration:3000
						})
					}
				})
			},
			// 二进制流转ascii
			ab2ascii(buffer) {
				var str = Array.prototype.map.call(
					new Uint8Array(buffer),
					function(bit) {
						return String.fromCharCode(bit);
					}
				)
				return str.join('');
			},
			// 向蓝牙写入数据
			BleWrite(instruction) {
				//instruction  写入的数据
				let _this = this
				let serviceId = _this.serviceId
				//characteristicId2  是支持write 特征uuid
				let characteristicId = _this.characteristicId2
				let deviceId = _this.deviceId
				//转换数据格式
				const buffer = _this.asciiToArrayBuffer(instruction);
				uni.writeBLECharacteristicValue({
					deviceId, // 蓝牙设备 deviceId
					serviceId, // 蓝牙服务uuid,即第二个uuid
					characteristicId, // 蓝牙特征值的 (即 writeId)
					value: buffer, // 这里的value是ArrayBuffer类型
					writeType: 'write',
					success(res) {
						console.log('指令下发成功==', res)
						//写入成功之后  如需接收数据   在上面的接收数据处获取返回的结果
					},
					fail(err) {
						console.log('指令发送失败', err)
						uni.showToast({
							icon: "none",
							title: "指令发送失败",
							duration: 3000
						})
					}
				})
			},
			// ascii  转  二进制流
			asciiToArrayBuffer(str) {
				if (!str) {
					return new ArrayBuffer(0);
				}
				var buffer = new ArrayBuffer(str.length);
				// let dataView = new DataView(buffer)
				var bufView = new Uint8Array(buffer);
				for (var i = 0, strLen = str.length; i < strLen; i++) {
					bufView[i] = str.charCodeAt(i);
				}
				return buffer;
			},
			scan(){
				uni.scanCode({
					onlyFromCamera:true,
					scanType:['barCode','qrCode','datamatrix','pdf417'],
					autoDecodeCharset:true,
					barCodeInput:false,
					hideAlbum:true,
					success:res=>{
						console.log(res)
					}
				})
			},
		}
	}
</script>

<style>
	.content {
		/* display: flex;
		justify-content: center;
		align-items: center;
		height: 500px; */
	}
	.content .iconfont {
		font-size: 200px;
		color:red;
		
	}
</style>
